<template>
  <div class="contBody">
    <h2 class="title">Popup标注</h2>
    <div id="popupMap" class="map__x">
      <!-- Popup -->
      <div id="popup" class="ol-popup">
        <a href="#" id="popup-closer" class="ol-popup-closer"></a>
        <div id="popup-content"></div>
      </div>
    </div>
  </div>
</template>

<script>
import { Map, View, Feature, Overlay } from "ol"; // 地图实例方法、视图方法
import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer";
import VectorSource from "ol/source/Vector";
import { Style, Stroke, Icon, Fill, Text } from "ol/style";
import { Point } from "ol/geom";
import XYZ from "ol/source/XYZ";
import "ol/ol.css"; // 地图样式

import blueIcon from "@/assets/images/blueIcon.png";
import bj from "@/assets/images/bj.png";

export default {
  name: "PopupPage",
  data() {
    return {
      map: null,
    };
  },
  mounted() {
    this.initMap();
  },
  methods: {
    changeStatus(status) {
      this.status = status;
    },
    initMap() {
      //示例标注点北京市的信息对象
      const featuerInfo = {
        geo: [116.28, 39.54],
        att: {
          //标注信息的标题内容
          title: "北京市(中华人民共和国首都)",
          //标注详细信息链接
          titleURL: "http://www.openlayers.org/",
          //标注内容简介
          text: "北京（Beijing），简称京，中华人民共和国首都、直辖市，中国的政治、文化和国际交往中心……",
          //标注的图片
          imgURL: bj,
        },
      };

      //实例化Vector要素，通过矢量图层添加到地图容器中
      const iconFeature = new Feature({
        geometry: new Point([116.28, 39.54]),
        //名称属性
        name: "北京市",
        //大概人口数（万）
        population: 2115,
      });
      const iconStyle = this.createLabelStyle(iconFeature);
      iconFeature.setStyle(iconStyle);

      //矢量标注的数据源
      const vectorSource = new VectorSource({
        features: [iconFeature],
      });

      //矢量标注图层
      const vectorLayer = new VectorLayer({
        source: vectorSource,
        zIndex: 2,
        visible: true,
      });

      // 地图实例
      this.map = new Map({
        target: "popupMap",
        layers: [
          new TileLayer({
            source: new XYZ({
              url: "http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7", // 新高德地图
            }),
            zIndex: 1,
            visible: true,
          }),
        ],
        view: new View({
          projection: "EPSG:4326",
          center: [120, 39],
          zoom: 6,
        }),
      });

      this.map.addLayer(vectorLayer);

      /**
       * 实现popup的html元素
       */
      const container = document.getElementById("popup");
      const content = document.getElementById("popup-content");
      const closer = document.getElementById("popup-closer");

      // 实例化overlay标注，添加到地图容器中
      const popup = new Overlay({
        element: container, // 要转换成overlay的HTML元素
        autoPan: true, //当前窗口可见
        positioning: "bottom-center", //Popup放置的位置
        stopEvent: false, //是否应该停止事件传播到地图窗口
        autoPanAnimation: {
          duration: 250, //当Popup超出地图边界时，为了Popup全部可见，地图移动的速度
        },
      });
      this.map.addOverlay(popup);

      /**
       * 添加关闭按钮的单击事件（隐藏popup）
       * @return {boolean} Don't follow the href.
       */
      closer.onclick = () => {
        //未定义popup位置
        popup.setPosition(undefined);
        //失去焦点
        closer.blur();
        return false;
      };

      //为地图容器添加单击事件监听
      this.map.on("click", (evt) => {
        //判断当前单击处是否有要素，捕获到要素时弹出popup
        const feature = this.map.forEachFeatureAtPixel(
          evt.pixel,
          function (feature) {
            return feature;
          }
        );
        if (feature) {
          //清空popup的内容容器
          content.innerHTML = "";
          //在popup中加载当前要素的具体信息
          this.addFeatrueInfo(featuerInfo);
          if (popup.getPosition() == undefined) {
            //设置popup的位置
            popup.setPosition(featuerInfo.geo);
          }
        }
      });
    },
    /**
     * 标注样式
     */
    createLabelStyle(feature) {
      return new Style({
        image: new Icon({
          anchor: [0.5, 60],
          anchorOrigin: "top-right",
          anchorXUnits: "fraction",
          anchorYUnits: "pixels",
          offsetOrigin: "top-right",
          opacity: 1,
          src: blueIcon,
        }),
        text: new Text({
          textAlign: "center",
          textBaseline: "middle",
          font: "normal 14px 微软雅黑",
          text: feature.get("name"),
          fill: new Fill({ color: "#aa3300" }),
          stroke: new Stroke({ color: "#ffcc33", width: 2 }),
        }),
      });
    },

    /**
     * 动态创建popup的具体内容
     * @param {string} title
     */
    addFeatrueInfo(info) {
      const content = document.getElementById("popup-content");
      //新增a元素
      let elementA = document.createElement("a");
      elementA.className = "markerInfo";
      elementA.href = info.att.titleURL;
      //elementA.innerText = info.att.title;
      this.setInnerText(elementA, info.att.title);
      // 新建的div元素添加a子节点
      content.appendChild(elementA);
      //新增div元素
      let elementDiv = document.createElement("div");
      elementDiv.className = "markerText";
      //elementDiv.innerText = info.att.text;
      this.setInnerText(elementDiv, info.att.text);
      // 为content添加div子节点
      content.appendChild(elementDiv);
      //新增img元素
      let elementImg = document.createElement("img");
      elementImg.className = "markerImg";
      elementImg.src = info.att.imgURL;
      // 为content添加img子节点
      content.appendChild(elementImg);
    },

    /**
     * 动态设置元素文本内容（兼容）
     */
    setInnerText(element, text) {
      if (typeof element.textContent == "string") {
        element.textContent = text;
      } else {
        element.innerText = text;
      }
    },
  },
};
</script>

<style lang="css" scoped>
.contBody .title {
  padding: 0 0 24px;
}
.map__x {
  width: 100%;
  height: 600px;
  border: 1px solid #eee;
}

.btn {
  text-align: left;
}
</style>

<style>
.ol-popup {
  position: absolute;
  background-color: white;
  -webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
  filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
  padding: 15px;
  border-radius: 10px;
  border: 1px solid #cccccc;
  bottom: 45px;
  left: -50px;
}

.ol-popup:after,
.ol-popup:before {
  top: 100%;
  border: solid transparent;
  content: " ";
  height: 0;
  width: 0;
  position: absolute;
  pointer-events: none;
}

.ol-popup:after {
  border-top-color: white;
  border-width: 10px;
  left: 48px;
  margin-left: -10px;
}

.ol-popup:before {
  border-top-color: #cccccc;
  border-width: 11px;
  left: 48px;
  margin-left: -11px;
}

.ol-popup-closer {
  text-decoration: none;
  position: absolute;
  top: 2px;
  right: 8px;
  color: #333;
}

.ol-popup-closer:after {
  content: "✖";
}

#popup-content {
  font-size: 14px;
  font-family: "微软雅黑";
}

#popup-content .markerInfo {
  font-weight: bold;
  color: #333;
}
</style>
